package com.sumer.psychology.blog.application.query;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.sumer.psychology.common.query.AbstractSimpleQueryApplicationService;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;

import javax.inject.Inject;
import java.util.List;
import java.util.regex.Pattern;

/**
 * 博客查询
 * <p/>
 * Created by zhu on 14/10/20.
 */
public class BlogQueryApplicationService extends AbstractSimpleQueryApplicationService {
    private static final String DB_NAME = "sumer_blog";

    private CategoryQueryApplicationService categoryQueryApplicationService;

    @Override
    protected String dbName() {
        return DB_NAME;
    }

    /**
     * 关键字查询文章
     *
     * @param keyword      key word
     * @param countPerPage count per page
     * @param offset       off set
     * @return json
     */
    public String findByKeyword(String keyword, int countPerPage, int offset) {
        DBObject queryCondition = new BasicDBObject(
                "title",
                Pattern.compile(".*" + keyword + ".*", Pattern.CASE_INSENSITIVE));
        queryCondition.put("availability", "ACTIVE");

        return findByCondition(countPerPage, offset, queryCondition);

    }

    /**
     * 查询作者下的文章
     *
     * @param authorId     author id
     * @param countPerPage count per page
     * @param offset       off set
     * @param keyword      key word
     * @return json
     */
    public String findByAuthor(String authorId, int countPerPage, int offset, String keyword) {
        DBObject queryCondition = new BasicDBObject()
                .append("author.identity", authorId)
                .append("title", Pattern.compile(".*" + keyword + ".*", Pattern.CASE_INSENSITIVE));
        queryCondition.put("availability", "ACTIVE");

        List<DBObject> results = findListByCondition(
                countPerPage,
                offset,
                queryCondition).toArray();

        for (DBObject result : results) {
            initializeContent(result);
            initializeCategory(result);
        }

        return serializeWithTotalCount(queryCondition, results);
    }

    /**
     * 查询一个目录下的文章
     *
     * @param categoryId   category id
     * @param countPerPage count per page
     * @param offset       off set
     * @return json
     */
    public String findByCategory(String categoryId, int countPerPage, int offset) {
        DBObject queryCondition = new BasicDBObject("categoryId", categoryId);
        queryCondition.put("availability", "ACTIVE");

        List<DBObject> results = db().getCollection(dbName())
                .find(queryCondition)
                .sort(new BasicDBObject("createTime", -1))
                .skip(offset).limit(countPerPage).toArray();

        for (DBObject result : results) {
            initializeContent(result);
            initializeCategory(result);
        }

        return serializeWithTotalCount(queryCondition, results);
    }

    /**
     * 查询作者回收站里的文章
     *
     * @param authorId author id
     * @return json
     */
    public String findOfRecycleBinByAuthor(String authorId) {
        DBObject queryCondition = new BasicDBObject("author.identity", authorId);
        queryCondition.put("availability", "DEACTIVE");

        DBCursor results = db().getCollection(dbName())
                .find(queryCondition)
                .sort(new BasicDBObject("createTime", -1));

        return serializeWithTotalCount(queryCondition, results);
    }

    @Override
    public String findById(String id) {
        DBObject dbObject = findOneWithStatus(id, "ACTIVE");
        if (dbObject == null) {
            return null;
        }

        dbObject.put("content", StringEscapeUtils.unescapeHtml4((String) dbObject.get("content")));
        initializeCategory(dbObject);

        return serialize(dbObject);
    }

    private void initializeCategory(DBObject result) {
        String categoryId = (String) result.get("categoryId");
        if (StringUtils.isNotBlank(categoryId)) {
            DBObject category = categoryQueryApplicationService.findCategoryById(categoryId);
            result.put("category", category);
        }
    }

    private void initializeContent(DBObject result) {
        String content = Jsoup.parse(StringEscapeUtils.unescapeHtml4((String) result.get("content"))).text();
        result.put("content", content.length() > 200 ? content.substring(0, 200) + "......" : content);
    }

    @Inject
    public void setCategoryQueryApplicationService(CategoryQueryApplicationService categoryQueryApplicationService) {
        this.categoryQueryApplicationService = categoryQueryApplicationService;
    }
}
